package org.jeecg.modules.system.exception;

import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.jeecg.common.api.vo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import java.io.EOFException;

/**
 * Multipart异常处理器
 */
@Slf4j
@RestControllerAdvice
public class MultipartExceptionHandler {

    /**
     * 处理MultipartException异常
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(MultipartException.class)
    public Result<String> handleMultipartException(MultipartException e) {
        log.error("Multipart请求处理异常: ", e);
        
        // 检查是否是客户端中断导致的异常
        if (isClientAbortException(e)) {
            log.warn("客户端中断了文件上传: {}", e.getMessage());
            // 对于客户端中断，我们返回一个更友好的消息而不是错误
            return Result.ok("客户端取消了文件上传");
        }
        
        return Result.error("文件上传失败，请重新尝试");
    }
    
    /**
     * 处理MissingServletRequestPartException异常
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(MissingServletRequestPartException.class)
    public Result<String> handleMissingServletRequestPartException(MissingServletRequestPartException e) {
        log.error("MissingServletRequestPartException异常: ", e);
        
        // 这个异常通常是客户端中断导致的
        log.warn("客户端中断了文件上传: {}", e.getMessage());
        return Result.ok("客户端取消了文件上传");
    }
    
    /**
     * 处理ClientAbortException异常
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(ClientAbortException.class)
    public Result<String> handleClientAbortException(ClientAbortException e) {
        log.error("ClientAbortException异常: ", e);
        
        // 客户端中断了连接
        log.warn("客户端中断了文件上传: {}", e.getMessage());
        return Result.ok("客户端取消了文件上传");
    }
    
    /**
     * 处理FileUploadException异常
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(FileUploadException.class)
    public Result<String> handleFileUploadException(FileUploadException e) {
        log.error("FileUploadException异常: ", e);
        
        // 检查是否是客户端中断导致的异常
        if (isClientAbortException(e)) {
            log.warn("客户端中断了文件上传: {}", e.getMessage());
            return Result.ok("客户端取消了文件上传");
        }
        
        return Result.error("文件上传失败，请重新尝试: " + e.getMessage());
    }
    
    /**
     * 检查是否是客户端中断导致的异常
     * @param e Exception
     * @return boolean
     */
    private boolean isClientAbortException(Exception e) {
        Throwable cause = e.getCause();
        while (cause != null) {
            if (cause instanceof EOFException || 
                cause instanceof ClientAbortException ||
                "java.io.EOFException".equals(cause.getClass().getName()) ||
                cause.getClass().getName().contains("ClientAbortException")) {
                return true;
            }
            cause = cause.getCause();
        }
        
        // 检查异常消息中是否包含特定的关键字
        String message = e.getMessage();
        if (message != null && (message.contains("EOFException") || 
                               message.contains("ClientAbort") || 
                               message.contains("Broken pipe"))) {
            return true;
        }
        
        // 检查异常堆栈中是否包含特定的类
        for (StackTraceElement element : e.getStackTrace()) {
            if (element.getClassName().contains("ClientAbortException") || 
                element.getClassName().contains("EOFException")) {
                return true;
            }
        }
        
        return false;
    }
}